#include "stdio.h"
#include "string.h"
#include "stdint.h"
#include "DevicesM3-S.h"


static M3STypeDef st_typeM3SData = {0};


#if 0

M3SMachineEnum enumM3SDecode(M3STypeDef *ptypeData, uint8_t ucValue)
{
    uint16_t usCheckSum = 0;
    uint8_t i = 0;

    if(ptypeData == NULL)
        return M3SError;

    if((ptypeData->frame.state == M3SStart) || (ptypeData->frame.state == M3SSucceed))
    {
        memset(ptypeData, 0, sizeof(M3STypeDef));
        ptypeData->frame.state = M3SHead;
    }

    ++ptypeData->frame.lengthRead;

    switch(ptypeData->frame.state)
    {
        case M3SHead:
            ptypeData->frame.head = (ptypeData->frame.head << 8) | ucValue;

            if(ptypeData->frame.lengthRead >= 2)
            {
                ptypeData->frame.state = (ptypeData->frame.head == M3S_FRAME_HEAD) ? M3SLength : M3SStart;
                ptypeData->frame.lengthRead = 0;
            }
            break;

        case M3SLength:
            ptypeData->frame.length = (ptypeData->frame.length << 8) | ucValue;

            if(ptypeData->frame.lengthRead >= 2)
            {
                ptypeData->frame.state = (ptypeData->frame.length <= M3S_FRAME_LEGNTH) ? M3SData : M3SStart;
                ptypeData->frame.lengthRead = 0;
            }
            break;

        case M3SData:
            ptypeData->data[ptypeData->frame.lengthRead + 3] = ucValue;

            if(ptypeData->frame.lengthRead >= ptypeData->frame.length - 2)
            {
                ptypeData->frame.state = M3SCehckSum;
                ptypeData->frame.lengthRead = 0;
            }
            break;

        case M3SCehckSum:
            ptypeData->frame.checkSum = (ptypeData->frame.checkSum << 8) | ucValue;

            if(ptypeData->frame.lengthRead >= 2)
            {
                for(i = 0; i < ptypeData->frame.length + 2; ++i)
                {
                    usCheckSum += ptypeData->data[i];
                }

                ptypeData->frame.state = (usCheckSum == ptypeData->frame.checkSum) ? M3SSucceed : M3SStart;
            }
            break;

        default: ptypeData->frame.state = M3SStart; break;
    }

    if(ptypeData->frame.state == M3SSucceed)
    {
        printf("\n\rframe:\r\n");
        printf("head: %04X\r\n", ptypeData->frame.head);
        printf("length: %d\r\n", ptypeData->frame.length);
        printf("concentration: %04X\r\n", ptypeData->frame.concentration);
        printf("count_10_50um: %04X\r\n", ptypeData->frame.count_10_50um);
        printf("count_50_200um: %04X\r\n", ptypeData->frame.count_50_200um);
        printf("count_200_500um: %04X\r\n", ptypeData->frame.count_200_500um);
        printf("count_500_1000um: %04X\r\n", ptypeData->frame.count_500_1000um);
        printf("count_1m: %04X\r\n", ptypeData->frame.count_1m);
        printf("checkSum: %04X\r\n", ptypeData->frame.checkSum);
        printf("state: %d\r\n", ptypeData->frame.state);
        printf("lengthRead: %d\r\n", ptypeData->frame.lengthRead);
    }

    return ptypeData->frame.state;
}

#else /* 杉川自研传感器 */

M3SMachineEnum enumM3SDecode(M3STypeDef *ptypeData, uint8_t ucValue)
{
    uint8_t ucCheckSum = 0;

    if(ptypeData == NULL)
        return M3SError;

    if((ptypeData->state == M3SStart) || (ptypeData->state == M3SSucceed))
    {
        memset(ptypeData, 0, sizeof(M3STypeDef));
        ptypeData->state = M3SHead;
    }

    ++ptypeData->lengthRead;

    switch(ptypeData->state)
    {
        case M3SHead:
            ptypeData->head = ucValue;
            ptypeData->state = (ptypeData->head == M3S_FRAME_HEAD) ? M3SReserved : M3SStart;
            break;

        case M3SReserved:
            ptypeData->reserved = ucValue;
            ptypeData->state = M3SLength;
            break;

        case M3SLength:
            ptypeData->length = ucValue;
            ptypeData->state = (ptypeData->length <= M3S_FRAME_LEGNTH) ? M3SData : M3SStart;
            break;

        case M3SData:
            ptypeData->value = (ptypeData->value << 8) | ucValue;
            ptypeData->state = (ptypeData->lengthRead >= 5) ? M3SCehckSum : ptypeData->state;
            break;

        case M3SCehckSum:
            ptypeData->checkSum = ucValue;

            ucCheckSum  = ptypeData->head;
            ucCheckSum += ptypeData->reserved;
            ucCheckSum += ptypeData->length;
            ucCheckSum += ptypeData->value >> 8;
            ucCheckSum += ptypeData->value & 0xFF;

            ptypeData->state = (ucCheckSum == ptypeData->checkSum) ? M3SSucceed : M3SStart;
            break;

        default: ptypeData->state = M3SStart; break;
    }

    if(ptypeData->state == M3SSucceed)
    {
        printf("\n\rM3S head: %02X, reserved: %d, length: %d, value: %d, checkSum: %02X\r\n", \
        ptypeData->head, ptypeData->reserved, ptypeData->length, ptypeData->value, ptypeData->checkSum);
    }

    return ptypeData->state;
}

#endif

int8_t cM3SSetInfo(M3STypeDef *ptypeData)
{
    if(ptypeData == NULL)
        return 1;

    st_typeM3SData = *ptypeData;

    return 0;
}

M3STypeDef *typeM3SGetInfo(void)
{
    return &st_typeM3SData;
}
